home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MPW_C / TCPSTUFF / FINGER.C < prev    next >
C/C++ Source or Header  |  1990-08-20  |  6KB  |  271 lines

  1. /*                    HISTORY
  2.  
  3.                     MacTCP Finger tool
  4.                     written by Matt Mashyna
  5.                     Carnegie Mellon,
  6.                     College of H&SS,
  7.                     Macintosh Initiative.
  8.                     Built from an ntp UDP example by Rob Chandok from CS
  9.                     which was base on BSD 4.3                    
  10.                     
  11.                     chandhok Tuesday, August 8, 1989 10:46:50 AM
  12.                     
  13.                     Made name lookup on cacheFault work, added printf of host name on connection,
  14.                     changed printf to puts, so a plan file with "%s" won't break this tool.
  15.                     
  16.                     fixed bug in lf2sp that could miss a lf in the first byte of "s",
  17.                     by changing while loop to a for loop.
  18.  
  19.                     mashyna Frisday, September 8, 1989 4:01:00 PM
  20.  
  21.                     Rebuilt foundation based on a standard H&SS TCP library.
  22.                     Old calls that used a minimal Stream ref replaced by TCPiopb parameter blocks.
  23. */
  24.  
  25. #include    <Types.h>
  26. #include    <Events.h>
  27. #include    <Math.h>
  28. #include     <fcntl.h>
  29. #include     <stdio.h>
  30. #include    <ErrMgr.h>
  31. #include    <CursorCtl.h>
  32. #include    <Errors.h>
  33. #include    <Devices.h>
  34. #include    <MacTCPCommonTypes.h>
  35. #include    <UDPPB.h>
  36. #include    <TCPPB.h>
  37. #include     <GetMyIPAddr.h>
  38. #include    <AddressXlation.h>
  39. #include    <signal.h>
  40. #include    <Time.h>
  41. #include    <tcplib.h>
  42.  
  43. extern char *malloc(), *strchr();
  44.  
  45. #define lf_char 10
  46. #define cr_char 13
  47. #define space_char 32
  48. #define BUFSIZ    4096
  49. #define TCPBUFSIZ 16384
  50.  
  51. void clean_exit(OSErr err, TCPiopb *tcppb);        /* forward */
  52.  
  53. TCPiopb     tcppb;                /* global so we can abort via signal */
  54.  
  55. void choke(int sig)
  56. {
  57.     #pragma unused(sig)
  58.     
  59.     (void) TCPReleaseStream(tcppb.tcpStream,tcppb.ioCRefNum);
  60.     fprintf(stderr,"Finger aborted\n");
  61.     exit(0);
  62. } /* close_listeners */
  63.  
  64. void     FailOSErr(
  65.     char        *msg,
  66.     OSErr        err,
  67.     TCPiopb *tcppb)
  68. {
  69.     if (err != noErr) {
  70.         fprintf(stderr,"%s errcode=%d\n",msg,err);
  71.         clean_exit (-1,tcppb);
  72.     }
  73. }
  74.  
  75. pascal void dnrDone(struct hostInfo *hostInfoPtr, char *userDataPtr)
  76. {
  77.     #pragma unused(hostInfoPtr)
  78.  
  79.     (*userDataPtr)++;
  80. }
  81.  
  82. void doDNRerr(OSErr err)
  83. {
  84.     switch (err) {
  85.         case nameSyntaxErr:
  86.             fprintf(stderr,"(Bad syntax in host name)\n");
  87.             break;
  88.         case noNameServer:
  89.             fprintf(stderr,"(No name server can be found for this host)\n");
  90.             break;
  91.         case authNameErr:
  92.             fprintf(stderr,"(This domain/host name does not exist)\n");
  93.             break;
  94.         case noAnsErr:
  95.             fprintf(stderr,"(None of the name servers are responding)\n");
  96.             break;
  97.         case dnrErr:
  98.             fprintf(stderr,"(Unknown error from the domain name server)\n");
  99.             break;
  100.     }
  101. }
  102.  
  103. char *inet_ntoa(ip_addr addr)
  104. {
  105.     char dnrdoneflag;
  106.     static struct hostInfo hi;
  107.     OSErr err;
  108.  
  109.     dnrdoneflag = 0; 
  110.     err = AddrToName(addr,&hi,&dnrDone,&dnrdoneflag);
  111.  
  112.     if (err == cacheFault) {
  113.         while (!dnrdoneflag) {
  114.             SpinCursor(1);
  115.             /* SystemTask? WaitNextEvent ? */
  116.         }
  117.         err = hi.rtnCode;
  118.     }
  119.     if (err == noErr) {
  120.         return hi.cname;
  121.     }
  122.     
  123.     /* if all else fails */
  124.     if ((err = AddrToStr(addr,hi.cname)) != noErr) {
  125.         doDNRerr(err);
  126.         return "??";
  127.     } else {
  128.         return hi.cname;
  129.     }
  130. }
  131.  
  132. void clean_exit(OSErr err, TCPiopb *tcppb)
  133. {
  134.     (void) TCPReleaseStream(tcppb->tcpStream,tcppb->ioCRefNum);
  135.     if(err) 
  136.         fprintf(stderr,"clean_exit(%d)\n",err);
  137.     (void) fflush(stderr);
  138.     
  139.     exit(err);
  140. }
  141.  
  142. main(argc, argv)
  143.     int argc;
  144.     char **argv;
  145. {
  146.     char        fbuff[BUFSIZ+1];    /* a read/write buffer                                             */
  147.     int            size;            /* actual size to write, max size into and actual size of a read */
  148.     OSErr        err;            /* function return codes                                         */
  149.     struct         hostInfo hp;
  150.     short        refnum;
  151.     char        * host,
  152.                 * user,
  153.                 * p,
  154.                 lastchar;
  155.     static char *noname = "\0";
  156.     char dnrdoneflag;
  157.     
  158.     InitCursorCtl(nil);
  159.  
  160.     if (argc < 2) {
  161.         fprintf(stderr,"Usage: %s  [user@]host\n",argv[0]);
  162.         clean_exit(-1,&tcppb);
  163.         }
  164.         
  165.     user = noname;
  166.     host = noname;
  167.     
  168.     p = strchr(argv[1],'@');
  169.     
  170.     if(p) {
  171.         user = argv[1];
  172.         *p='\0';
  173.         host = p+1;
  174.         }
  175.         
  176.     bzero((char *)&tcppb,sizeof(tcppb));
  177.  
  178.     if(strlen(host) == 0) {
  179.         fprintf(stderr,"No host specified\n");
  180.         clean_exit(-1,&tcppb);
  181.         }
  182.         
  183.     if(OpenResolver(NIL)) {
  184.         fprintf(stderr,"Failed to open resolver\n");
  185.         exit(0);
  186.         }
  187.     
  188.     if(opendriver(".IPP",&refnum)) {
  189.         fprintf(stderr,"Failed to open IP driver\n");
  190.         exit(0);
  191.         }
  192.  
  193.         dnrdoneflag = 0; 
  194.         err = StrToAddr(host,&hp,&dnrDone,&dnrdoneflag);
  195.  
  196.         if (err == cacheFault) {
  197.             while (!dnrdoneflag) {
  198.                 SpinCursor(1);
  199.                 /* SystemTask? WaitNextEvent ? */
  200.             }
  201.             err = hp.rtnCode;
  202.  
  203.         }
  204.         /* check for uncaught error in dnr!  */
  205.         if ((err == noErr) && (hp.addr[0] == 0)) {
  206.             err = dnrErr;
  207.         }
  208.         if (err != noErr) {
  209.             fprintf(stderr, "\nNo such host: %s error:%d\n", host,err);
  210.             doDNRerr(err);
  211.             clean_exit(-1,&tcppb);
  212.         }
  213.             
  214.     sprintf(fbuff,"%s\r\n",user);        /* finger expects to have CR & LF after the name */
  215.  
  216.     size = BUFSIZ;
  217.     
  218.     tcppb.ioCRefNum = refnum;
  219.     
  220.     (void) signal(SIGINT,choke);
  221.  
  222.     FailOSErr("Create Stream",CreateTCPStream(TCPBUFSIZ,&tcppb),&tcppb);        /* create a port to use with TCPBUFSIZ size buffer */        
  223.     fprintf(stdout,"[%s]\n",inet_ntoa(hp.addr[0]));                             /* show that we are connected to the host */
  224.     (void) fflush(stdout);                                                        /* make sure it shows up*/
  225.     FailOSErr("Open Stream",OpenTCPStream(FINGER_PORT,&hp,&tcppb),&tcppb);        /* now open a connection with the other host */
  226.     FailOSErr("Write Stream",WriteTCPStream(fbuff,&size,&tcppb,false),&tcppb);    /* send it our finger request */
  227.  
  228.     if (err == ipDestDeadErr) {     /* are there other codes here we should special case? */
  229.         fprintf(stderr,"Host %s not responding, errcode=%d\n",inet_ntoa(hp.addr[0]),err);
  230.         clean_exit(0,&tcppb);
  231.         }
  232.         
  233.     else if (err != noErr) {
  234.         fprintf(stderr,"TCPsend fails errcode=%d\n",err);
  235.         clean_exit(0,&tcppb);
  236.         }
  237.     
  238.     Show_Cursor(WATCH_CURSOR);                                 /* wait for the host to reply */
  239.     while(err != connectionClosing && err != commandTimeout) {    /* loop until host has no more to send */
  240.         size = BUFSIZ;
  241.         err = ReadTCPStream(fbuff,&size,&tcppb,false);                /* read from remote host */
  242.         
  243.         if (err == commandTimeout) {
  244.             fprintf(stderr,"\n\t* Timeout *\n");
  245.             clean_exit(0,&tcppb);
  246.             }
  247.         else if (err == connectionClosing) continue;            /* will be caught in loop above */
  248.         
  249.         else if (err != noErr) {
  250.             fprintf(stderr,"packet:TCPRead fails (%d)\n", err);
  251.             clean_exit(0,&tcppb);
  252.             }
  253.         for (lastchar = 0, p = fbuff; p < fbuff+size; p++) {
  254.             switch (*p) {
  255.                 case lf_char:
  256.                     if (lastchar == cr_char) {
  257.                         /* skip the lf */
  258.                     }
  259.                     break;
  260.                 default:
  261.                     putchar(*p);
  262.             }
  263.             lastchar = *p;
  264.         }
  265.         (void) fflush(stdout);                                    /* make sure it shows up*/
  266.     }
  267.  clean_exit(0,&tcppb); 
  268. }                /* end of main */
  269.  
  270.  
  271.